package org.tjc.net.manager;

import org.apache.commons.lang3.StringUtils;
import org.tjc.net.manager.bean.HttpRequest;
import org.tjc.net.manager.bean.HttpResponse;
import org.tjc.net.manager.config.json.ContextFacade;
import org.tjc.net.manager.config.json.NgLocationModule;
import org.tjc.net.manager.config.json.NgServerModule;
import org.tjc.net.manager.exception.ParseHttpException;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * @Author: tjc
 * @description
 * @Date Created in 17:23 2020-11-25
 */
public class HttpProcessor {

    public static final Logger log = Logger.getLogger(HttpProcessor.class.getName());

    private HttpAdapter httpAdapter = new HttpAdapter();

    byte[] buffer = new byte[2048];

    private ContextFacade context;

    public HttpProcessor(ContextFacade context) {
        this.context = context;
    }

    public void process(Socket socket) {
        InputStream input = null;
        try (Socket curSocket = socket){
            input = socket.getInputStream();
            int len = input.read(buffer);
            String message = new String(buffer, 0, len);

            //todo
            HttpRequest request = HttpRequest.parse(message);

            NgServerModule server = context.getServer();

            NgLocationModule location = matchLocation(server);
            String socketAddress = "www.bilibili.com";
            InetAddress netAddress = InetAddress.getByName(socketAddress);
            Socket proxySocket = new Socket( socketAddress, 80);
            request.setHeader("Host", "www.bilibili.com");
            String proxyMsg = request.toMessage();

            try {
                proxySocket.getOutputStream().write(proxyMsg.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
            byte[] bytes = new byte[2048];

            try (InputStream proxyInput = proxySocket.getInputStream();){
                proxyInput.read(bytes);
                socket.getOutputStream().write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    private NgLocationModule matchLocation(NgServerModule server) {
        return null;
    }

    private void back(Socket socket, HttpResponse response) {
        return;
    }

    private HttpResponse proxy(HttpRequest proxyRequest) {
        return null;
    }

    private class RouteManager {

    }

//    private HttpRequest matchAndDecorate(HttpRequest request, Socket s) {
//        //match location
//        NgServerModule server = context.getServer();
//        NgLocationModule location = null;
//        for(NgLocationModule l : server.getLocations()) {
//            if(l.getPath().equals(request.getUrl())) {
//                location = l;
//            }
//        }
//        Socket proxySocket = createSocket(proxyRequest);
//
//        String proxyMsg = proxyRequest.toMessage();
//
//        try {
//            proxySocket.getOutputStream().write(proxyMsg.getBytes());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        byte[] bytes = new byte[2048];
//
//        try (InputStream input = proxySocket.getInputStream();){
//            input.read(bytes);
//            s.getOutputStream().write(bytes);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }


//    private Socket createSocket(HttpRequest proxyRequest) {
//        InetAddress netAddress = null;
//        try {
//            netAddress = InetAddress.getByName(proxyRequest.getDomain());
//        } catch (UnknownHostException e) {
//            e.printStackTrace();
//        }
//        Socket socket = null;
//        try {
//            socket = new Socket(netAddress, proxyRequest.getPort());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return socket;
//    }



    private static String HTTP11 = "HTTP/1.1";

    private boolean isHttp(HttpRequest request) {
        return request.getVersion().equals(HTTP11);
    }

    private static String METHOD_GET = "GET";
    private static String METHOD_POST = "POST";



    private static String LINE_SEPARATOR = "\r\n";

    private static int DEFAULT_PORT = 80;

    private static boolean checkMethodFormat(String method) {
        switch (method) {
            case "GET":
            case "POST":
                return true;
            default:
                throw new ParseHttpException("unexpect http method: " + method);
        }
    }

}
